/* 
 * File:   BoundingVolumeHierarchy.cpp
 * Author: brady
 * 
 * Created on August 27, 2011, 5:38 PM
 */

#include <acceleration/BoundingVolumeHierarchy.h>

BoundingVolumeHierarchy::BoundingVolumeHierarchy() {
    rootNode = NULL;
    shapes = vector<Shape*>();
}

BoundingVolumeHierarchy::BoundingVolumeHierarchy(const BoundingVolumeHierarchy& orig) {
}

BoundingVolumeHierarchy::~BoundingVolumeHierarchy() {
    if(rootNode != NULL){
        rootNode->~BVHNode();
    }
}

void BoundingVolumeHierarchy::addShape(Shape* shape){
    shapes.push_back(shape);
}
void BoundingVolumeHierarchy::finalize(){
    rootNode = new BVHNode(shapes, BVHNode::X_AXIS);
}
IntersectionResult BoundingVolumeHierarchy::getFirstIntersection(IntersectionParams& ip){
    IntersectionResult ir;
    rootNode->testIntersect(ip, ir);
    return ir;
}
vector<IntersectionResult> BoundingVolumeHierarchy::getAllIntersections(IntersectionParams& ip){
    vector<IntersectionResult> results;
    IntersectionResult ir;
    while (rootNode->testIntersect(ip, ir)){
        results.push_back(ir);
        ip.setTMin(ir.tVal + FLT_EPSILON);
    }
    return results;
}
IntersectionResult BoundingVolumeHierarchy::getAnyIntersection(IntersectionParams& ip){
    return getFirstIntersection(ip); //yeah, it defeats the purpose
}

vector<Shape*> BoundingVolumeHierarchy::getBoundingBoxIntersections(const BoundingBox& box){
    vector<Shape*> list;
    rootNode->boundingBoxIntersections(box, list);
    return list;
}